package com.devshephard.juchm.reentrantlock;



import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/* 它具备如下特点
        可重入
        可中断
        可以设置超时时间
        可以设置为公平锁
        支持多个条件变量
        颗粒度较小
        同样使用了monitor锁
 */

public class ReentrantLockDemo {

    public static void main(String[] args) throws InterruptedException {

        ReentrantLockClazz reentrantLockClazz = new ReentrantLockClazz();

        //普通使用
        new Thread(()->{
            reentrantLockClazz.methodBaseUse();
        },"A").start();

        new Thread(()->{
            reentrantLockClazz.methodBaseUse();
        },"B").start();


        //可重入体现,可重入是指同一个线程如果首次获得了这把锁，那么因为它是这把锁的拥有者，因此有权利再次获取这把锁
        //如果是不可重入锁，那么第二次获得锁时，自己也会被锁挡住
        //reentrantLockClazz.method1();


    }

}


class ReentrantLockClazz{

    //Reentrantlock是在对象内创建的一把锁,用于锁住对象
    private ReentrantLock reentrantLock = new ReentrantLock();

    //普通使用
    public String methodBaseUse(){

        //加锁
        reentrantLock.lock();

        System.out.println(Thread.currentThread().getName() + "获取到了锁！");

        try{
           TimeUnit.SECONDS.sleep(6);
        }catch (Exception e){
           e.printStackTrace();
        }finally {
            //Reentrantlock必须要进行解锁
            reentrantLock.unlock();
        }

        return "执行完成！";
    }

    //可重入体现
    public void method1() throws InterruptedException {
        reentrantLock.lock();
        try {
            System.out.println("execute method1");
            method2();
        } finally {
            reentrantLock.unlock();
        }
    }
    public  void method2() throws InterruptedException {
        reentrantLock.lock();
        try {
            System.out.println("execute method2");
            method3();
        } finally {
            reentrantLock.unlock();
        }
    }
    public  void method3() throws InterruptedException {
        reentrantLock.lock();
        try {
            System.out.println("execute method3");
        } finally {
            reentrantLock.unlock();
        }
    }


}